module Data.Expr
    where

newtype NonNegative a = NonNegative a

toNonNegative :: (Num a, Ord a) => a -> NonNegative a
toNonNegative x
  | x < 0 = error "Only non-negative values are allowed."
  | otherwise = NonNegative x

fromNonNegative :: NonNegative a -> a
fromNonNegative (NonNegative x) = x

data ArithmeticOperand a = ArithmeticOperand (NonNegative a)

data ArithmeticOperator = Add | Subtract

data ArithmeticExp a b = PlainArithmeticExp ArithmeticOperator (ArithmeticOperand a) (ArithmeticOperand b)
    | LCompound ArithmeticOperator (ArithmeticExp a a) (ArithmeticOperand b)
    | RCompound ArithmeticOperator (ArithmeticOperand a) (ArithmeticExp b b)
    | BCompound ArithmeticOperator (ArithmeticExp a a) (ArithmeticExp b b)

-- i.e: data NonEmptyList a = Single a | Cons a (NonEmptyList a) 